package dk.itu.spct;

import java.util.ArrayList;
import java.util.List;

import org.mt4j.AbstractMTApplication;
import org.mt4j.MTApplication;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.visibleComponents.widgets.MTImage;
import org.mt4j.components.visibleComponents.widgets.MTTextArea;
import org.mt4j.components.visibleComponents.widgets.buttons.MTImageButton;
import org.mt4j.input.inputData.InputCursor;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.unistrokeProcessor.UnistrokeEvent;
import org.mt4j.input.inputProcessors.componentProcessors.unistrokeProcessor.UnistrokeProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.unistrokeProcessor.UnistrokeUtils.Direction;
import org.mt4j.input.inputProcessors.componentProcessors.unistrokeProcessor.UnistrokeUtils.UnistrokeGesture;
import org.mt4j.input.inputProcessors.globalProcessors.CursorTracer;
import org.mt4j.sceneManagement.AbstractScene;
import org.mt4j.sceneManagement.transition.BlendTransition;
import org.mt4j.sceneManagement.transition.FadeTransition;
import org.mt4j.util.MT4jSettings;
import org.mt4j.util.MTColor;
import org.mt4j.util.font.FontManager;
import org.mt4j.util.math.Vector3D;
import org.mt4j.util.opengl.GLFBO;

import processing.core.PImage;

public class GestureDefinitionScene extends AbstractScene {
	
	private AbstractMTApplication mtApp;
	private UnistrokeProcessor usp;
	
	final static List<Vector3D> points = new ArrayList<Vector3D>();
	

	public GestureDefinitionScene(MTApplication mtApplication, String name) {
		super(mtApplication, name);
		this.mtApp = mtApplication;
		
		this.setClearColor(new MTColor(200, 200, 200, 200)); //set background color to boring grey
		this.registerGlobalInputProcessor(new CursorTracer(mtApp, this)); //show where mouse touches
		
		//Create a textfield
		MTTextArea textField = new MTTextArea(mtApp, FontManager.getInstance().createFont(mtApp, "arial.ttf", 
				50, MTColor.BLACK)); 
		textField.setNoFill(true);
		textField.setNoStroke(true);
		textField.setText("Draw a personal gesture of your choice");
		this.getCanvas().addChild(textField);
		textField.setPositionGlobal(new Vector3D(mtApp.width/2, mtApp.height/9f));
		textField.unregisterAllInputProcessors();
	
		//initialize unistroke processor
		usp = new UnistrokeProcessor(mtApp);
	
		//register the input processor at canvas of scene
		this.getCanvas().registerInputProcessor(usp);
		
		//listen to the unistroke gestures
		this.getCanvas().addGestureListener(UnistrokeProcessor.class, new IGestureEventListener() {
				public boolean processGestureEvent(MTGestureEvent ge) {
					UnistrokeEvent ue = (UnistrokeEvent)ge;
					InputCursor cursor = ue.getCursor();
					Vector3D point = new Vector3D();
						switch (ue.getId()) {
						case UnistrokeEvent.GESTURE_STARTED:
							getCanvas().addChild(ue.getVisualization());
							point = cursor.getPosition();
							//remove points of last gesture, when new gesture is started
							if(points.size()>0)
								points.clear();
							points.add(point);
							System.out.println("Gesture started at: " + point.toString());
							break;
						case UnistrokeEvent.GESTURE_UPDATED:
							point = cursor.getPosition();
							points.add(point);
							System.out.println("Gesture updated at: " + point.toString());
							break;
						case UnistrokeEvent.GESTURE_ENDED:
							point = cursor.getPosition();
							points.add(point);
							System.out.println("Gesture ended at: " + point.toString());
							UnistrokeGesture g = ue.getGesture();
							System.out.println("Recognized gesture: " + g);
							break;
						default:
							break;
						}
					return false;
				}
			});
		
		//Button to change to the previous scene on the scene stack
		PImage arrow = mtApp.loadImage("dk/itu/spct/data/arrowRight.png");
		MTImageButton previousSceneButton = new MTImageButton(mtApp, arrow);
		previousSceneButton.setNoStroke(true);
		if (MT4jSettings.getInstance().isOpenGlMode())
			previousSceneButton.setUseDirectGL(true);
		previousSceneButton.addGestureListener(TapProcessor.class, new IGestureEventListener() {
			public boolean processGestureEvent(MTGestureEvent ge) {
				TapEvent te = (TapEvent)ge;
				if (te.isTapped()){
					addGesture();
					ImageScene is = (ImageScene) mtApp.getScene("UI");
					is.listenForCustomGesture(usp);
					/*ArrayList<MTImage> images = is.getImages();
					for(MTImage i : images)
					{
						i.registerInputProcessor(usp);
						i.addGestureListener(UnistrokeProcessor.class, new IGestureEventListener() {
							public boolean processGestureEvent(MTGestureEvent ge) {
								UnistrokeEvent ue = (UnistrokeEvent)ge;
									switch (ue.getId()) {
									case UnistrokeEvent.GESTURE_STARTED:
										getCanvas().addChild(ue.getVisualization());
										break;
									case UnistrokeEvent.GESTURE_UPDATED:
										break;
									case UnistrokeEvent.GESTURE_ENDED:
										UnistrokeGesture g = ue.getGesture();
										System.out.println("Recognized gesture: " + g);
										break;
									default:
										break;
									}
									return false;
							}
						});
					}*/
					
					mtApp.changeScene(is);
					//mtApp.popScene();
				}
				return true;
			}
		});
		getCanvas().addChild(previousSceneButton);
		previousSceneButton.setPositionGlobal(new Vector3D(mtApp.width - previousSceneButton.getWidthXY(TransformSpace.GLOBAL) - 30, mtApp.height - previousSceneButton.getHeightXY(TransformSpace.GLOBAL) - 30, 0));
		
		//set scene transition
		if (MT4jSettings.getInstance().isOpenGlMode() && GLFBO.isSupported(mtApp))
			this.setTransition(new BlendTransition(mtApp, 700));
		else{
			this.setTransition(new FadeTransition(mtApp, 1700));
		}

	}
	
		private void addGesture(){
			//add custom gesture to unistroke processor
			if(points.size()>0){
				printPoints();
				usp.getUnistrokeUtils().getRecognizer().addTemplate(UnistrokeGesture.CUSTOMGESTURE, points, Direction.CLOCKWISE);
				usp.getUnistrokeUtils().getRecognizer().addTemplate(UnistrokeGesture.CUSTOMGESTURE, points, Direction.COUNTERCLOCKWISE);
				System.out.println("CUSTOMGESTURE ADDED");
			}
	}
	
	
	public void printPoints()
	{
		String p = "Points: \n";
		for(Vector3D point : points)
			p += point.toString() + "\n";
		
		System.out.println(p);
	}
	

	public void onEnter() {
		System.out.println("Entered scene: " +  this.getName());
	}
	
	public void onLeave() {	
		System.out.println("Left scene: " +  this.getName());
	}
}
